/**
* @file  graphForce
* @date 2024-05-23
*/

import React, { useEffect, useRef } from 'react';
import * as d3 from "d3";


const GraphForce = () => {
  const svgRef = useRef(null);

  useEffect(()=>{
    const width = 928;
    const height = 680;
  
    var nodes: any[] = [{ id: "桂林" }, { id: "广州" },
    { id: "厦门" }, { id: "杭州" },
    { id: "上海" }, { id: "青岛" },
    { id: "天津" }];
  
    var links: any[] = [{ source: 0, target: 1 }, { source: 0, target: 2 },
    { source: 0, target: 3 }, { source: 1, target: 4 },
    { source: 1, target: 5 }, { source: 1, target: 6 }];
  
  
    // 创建svg容器
    const svg = d3.select(svgRef.current)
      .append('svg')
      .attr('width', width)
      .attr('height', height)
      .attr('class', 'chart')
      .style('background-color','blue')
      
   // 随机颜色
   const color = d3.scaleOrdinal(d3.schemeCategory10);
    const simulation = d3.forceSimulation(nodes) 
    .force("charge", d3.forceManyBody().strength(-200)) // 电荷力 相互之间的作用力
    .force("center", d3.forceCenter(width / 2, height / 2)) // 用指定的x坐标和y坐标创建一个居中力
      // 连接力
      .force('link', d3.forceLink(links).distance(100))
      .on("tick", ticked)
      // 在 y轴方向上施加一个力 
      .force('y', d3.forceY().strength(0.025)) 
      // 电荷力 
      .force('charge', d3.forceManyBody()) 
      // 碰撞力
      .force('collision', d3.forceCollide().radius(d => 4)) 
      //  向心力
      .force('center', d3.forceCenter(width / 2, height / 2))
  
      function ticked() {
      lines
          .attr("x1", (d) => d.source.x)
          .attr("y1", (d) => d.source.y)
          .attr("x2", (d) => d.target.x)
          .attr("y2", (d) => d.target.y);
  
      // 这里就不适合 去改变circle的圆心位置了，因为有文字存在，改变整个circleGroup的transform
      nodesCircle.attr("transform", function (d) {
          // d.fx=d.x;d.fy=d.y; 固定位置
          return "translate(" + d.x + ", " + d.y + ")";
      });
  }
  
  
      // 画线
    function drawLine() {
      let lines = svg.append("g")
          .selectAll(".force-line")
          .data(links)
          .enter()
          .append("line")
          .attr("class", "line")
          .attr("stroke", "#999")
          .attr("stroke-width", "1px");
      return lines;
    }
    let lines = drawLine();
  
  // 画节点节点盒子
  
  function drawCircle() {
    let nodeGroups = svg.append("g")
        .attr("class", "nodes-box")
        .selectAll(".force-node")
        .data(nodes)
        .enter()
        .append("g")
        .attr("class", "force-circle")
  
    nodeGroups.append("circle")
        .attr("class", "force-circle")
        .attr("r", 20)
        .style("fill", function (d, i) {
          return color(i.toString());
        });
  
    nodeGroups.append("text")
        .attr("class", "force-text")
        .attr("dy", ".33em")
        .attr("font-size", "12px")
        .attr("text-anchor", "middle")
        .style("fill", "blue")
        .text(d => d.id);
    return nodeGroups;
  }
  let nodesCircle = drawCircle();
  } ,[])
 

 
  return <svg ref={svgRef} />
};


export default GraphForce;
